package com.finance.main;

import com.finance.console.common.ConsoleInput;
import com.finance.console.common.Constant;
import com.finance.console.common.FinanceException;
import com.finance.console.dao.UserDAO;
import com.finance.console.entity.AnalysisResult;
import com.finance.console.entity.Budget;
import com.finance.console.entity.IncomeExpense;
import com.finance.console.entity.StatResult;
import com.finance.console.entity.User;
import com.finance.console.service.analysis.ConsumptionAnalysisService;
import com.finance.console.service.budget.BudgetService;
import com.finance.console.service.record.IncomeExpenseService;
import com.finance.console.service.report.ReportService;
import com.finance.console.service.statisticc.FinancialStatService;
import com.finance.console.service.user.UserService;
import com.finance.console.service.user.UserServiceImpl;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Calendar;

public class MainConsole {
    // 服务层实例（与项目现有服务对应）
    private static final UserDAO userDAO = new UserDAO();
    private static final IncomeExpenseService recordService = new IncomeExpenseService();
    private static final BudgetService budgetService = new BudgetService();
    private static final FinancialStatService statService = new FinancialStatService();
    private static final ReportService reportService = new ReportService();
    private static final ConsumptionAnalysisService analysisService = new ConsumptionAnalysisService();
    private static User loginUser = null; // 当前登录用户
    private static final UserService userService = new UserServiceImpl();

    public static void main(String[] args) {
        System.out.println("===== 个人财务智能分析系统 =====");
        while (true) {
            // 未登录时显示登录菜单
            if (loginUser == null) {
                String choice = ConsoleInput.getString(Constant.LOGIN_MENU);
                switch (choice) {
                    case "1":
                        handleLogin();
                        break;
                    case "2":
                        handleRegister();
                        break;
                    case "3":
                        System.out.println("感谢使用，再见！");
                        return;
                    default:
                        System.out.println("无效选择，请重新输入");
                }
            } else {
                // 登录后显示主功能菜单
                showMainFunctionMenu();
            }
        }
    }

    // 登录处理
    private static void handleLogin() {
        try {
            String username = ConsoleInput.getString("请输入用户名：");
            String password = ConsoleInput.getString("请输入密码：");
            User user = userDAO.findByUsername(username);
            if (user == null) {
                System.out.println("用户名不存在");
                return;
            }
            if (!com.finance.console.common.EncryptUtils.checkPassword(password, user.getPassword())) {
                System.out.println("密码错误");
                return;
            }
            loginUser = user;
            System.out.println("登录成功！欢迎回来，" + user.getRealName() + "！");
        } catch (SQLException e) {
            System.out.println("登录失败：" + e.getMessage());
        }
    }

    // 注册处理
    private static void handleRegister() {
        try {
            String username = ConsoleInput.getString("请设置用户名：");
            if (userDAO.findByUsername(username) != null) {
                System.out.println("用户名已存在");
                return;
            }
            String password = ConsoleInput.getString("请设置密码：");
            String realName = ConsoleInput.getString("请输入真实姓名：");

            User user = new User();
            user.setUsername(username);
            user.setPassword(com.finance.console.common.EncryptUtils.encryptPassword(password));
            user.setRealName(realName);
            user.setRole("USER");
            user.setStatus(1);
            user.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            int rows = userDAO.addUser(user);
            if (rows > 0) {
                System.out.println("注册成功，请登录");
            } else {
                System.out.println("注册失败");
            }
        } catch (SQLException e) {
            System.out.println("注册失败：" + e.getMessage());
        }
    }

    // 主功能菜单
    private static void showMainFunctionMenu() {
        StringBuilder menu = new StringBuilder("\n===== 功能菜单 =====\n");
        // 公共功能
        menu.append("1. 收支记录管理\n")
                .append("2. 预算管理\n")
                .append("3. 财务统计\n")
                .append("4. 消费分析\n")
                .append("5. 生成报表\n");

        // 管理员专属功能
        if (userService.isAdmin(loginUser)) {
            menu.append("6. 用户管理\n")
                    .append("7. 系统设置\n")
                    .append("8. 退出登录\n");
        } else {
            menu.append("6. 退出登录\n");
        }

        String choice = ConsoleInput.getString(menu + "请选择：");
        handleMenuChoice(choice);
    }

    // 菜单选择处理
    private static void handleMenuChoice(String choice) {
        if (userService.isAdmin(loginUser)) {
            // 管理员选项处理
            switch (choice) {
                case "1": handleRecordManagement(); break;
                case "2": handleBudgetManagement(); break;
                case "3": handleFinancialStat(); break;
                case "4": handleConsumptionAnalysis(); break;
                case "5": handleGenerateReport(); break;
                case "6": handleUserManagement(); break;
                case "7": handleSystemSetting(); break;
                case "8":
                    loginUser = null;
                    System.out.println("已退出登录");
                    break;
                default: System.out.println("无效选择");
            }
        } else {
            // 普通用户选项处理
            switch (choice) {
                case "1": handleRecordManagement(); break;
                case "2": handleBudgetManagement(); break;
                case "3": handleFinancialStat(); break;
                case "4": handleConsumptionAnalysis(); break;
                case "5": handleGenerateReport(); break;
                case "6":
                    loginUser = null;
                    System.out.println("已退出登录");
                    break;
                default: System.out.println("无效选择");
            }
        }
    }

    // 收支记录管理子菜单
    private static void handleRecordManagement() {
        String menu = "\n===== 收支记录管理 =====\n" +
                "1. 添加收入\n" +
                "2. 添加支出\n" +
                "3. 查看当月记录\n" +
                "4. 返回上一级\n" +
                "请选择：";
        String choice = ConsoleInput.getString(menu);
        switch (choice) {
            case "1":
            case "2":
                addIncomeExpense(choice);
                break;
            case "3":
                viewMonthlyRecords();
                break;
            case "4":
                return;
            default:
                System.out.println("无效选择");
        }
    }

    // 添加收支记录
    private static void addIncomeExpense(String type) {
        try {
            String category = ConsoleInput.getString("请输入" + (type.equals("1") ? "收入" : "支出") + "分类：");
            double amount = ConsoleInput.getAmount("请输入金额：");

            IncomeExpense record = new IncomeExpense();
            record.setUserId(loginUser.getId());
            record.setType(type.equals("1") ? Constant.INCOME : Constant.EXPENSE);
            record.setCategory(category);
            record.setAmount(new BigDecimal(amount));
            record.setTime(new Date());

            recordService.addRecord(record);
            System.out.println("记录添加成功");
        } catch (Exception e) {
            System.out.println("操作失败：" + e.getMessage());
        }
    }

    // 查看当月记录
    private static void viewMonthlyRecords() {
        String yearMonth = ConsoleInput.getString("请输入年月（格式：yyyy-MM）：");
        String type = ConsoleInput.getString("1.收入 2.支出 3.全部，请选择：");

        String queryType = "3".equals(type) ? null : ("1".equals(type) ? Constant.INCOME : Constant.EXPENSE);
        List<IncomeExpense> records = recordService.getRecordsByMonth(loginUser.getId(), yearMonth, queryType);

        if (records.isEmpty()) {
            System.out.println("无相关记录");
            return;
        }

        System.out.println("\n===== " + yearMonth + " 记录列表 =====");
        for (IncomeExpense record : records) {
            System.out.printf("类型：%s | 分类：%s | 金额：%.2f元 | 时间：%s%n",
                    record.getType(),
                    record.getCategory(),
                    record.getAmount(),
                    new SimpleDateFormat("yyyy-MM-dd HH:mm").format(record.getTime())
            );
        }
    }

    // 预算管理子菜单
    private static void handleBudgetManagement() {
        String menu = "\n===== 预算管理 =====\n" +
                "1. 添加预算\n" +
                "2. 查看预算\n" +
                "3. 修改预算\n" +
                "4. 删除预算\n" +
                "5. 返回上一级\n" +
                "请选择：";
        String choice = ConsoleInput.getString(menu);
        switch (choice) {
            case "1":
                // 区分月度和通用预算添加
                String addType = ConsoleInput.getString("1. 月度预算 2. 通用预算，请选择：");
                if ("1".equals(addType)) {
                    addMonthlyBudget();
                } else if ("2".equals(addType)) {
                    addGeneralBudget();
                } else {
                    System.out.println("无效选择");
                }
                break;
            case "2":
                queryBudget();
                break;
            case "3":
                updateBudget();
                break;
            case "4":
                deleteBudget();
                break;
            case "5":
                return;
            default:
                System.out.println("无效选择");
        }
    }

    // 查看预算
    private static void queryBudget() {
        String cycle = ConsoleInput.getString("请输入查询周期（月/季度/年）：");
        List<Budget> budgets = budgetService.getBudgetsByCycle(loginUser.getId(), cycle);

        if (budgets.isEmpty()) {
            System.out.println("无预算记录");
            return;
        }

        System.out.println("\n===== " + cycle + " 预算列表 =====");
        System.out.printf("%-6s %-10s %-10s %-8s %-12s %-12s%n",
                "ID", "分类", "金额(元)", "周期", "开始日期", "结束日期");
        for (Budget budget : budgets) {
            System.out.printf("%-6d %-10s %-10.2f %-8s %-12s %-12s%n",
                    budget.getBudgetId(),
                    budget.getCategory(),
                    budget.getAmount(),
                    budget.getCycle(),
                    new SimpleDateFormat("yyyy-MM-dd").format(budget.getStartDate()),
                    new SimpleDateFormat("yyyy-MM-dd").format(budget.getEndDate())
            );
        }
    }

    // 添加月度预算（快捷方法）
    private static void addMonthlyBudget() {
        try {
            String category = ConsoleInput.getString("请输入预算分类：");
            double amount = ConsoleInput.getAmount("请输入预算金额：");
            String yearMonth = ConsoleInput.getString("请输入月份（格式：yyyy-MM）：");

            budgetService.addMonthlyBudget(loginUser.getId(), category, amount, yearMonth);
            System.out.println("月度预算添加成功");
        } catch (FinanceException e) {
            System.out.println(e.getMessage());
        }
    }

    // 添加通用预算（支持任意周期）
    private static void addGeneralBudget() {
        try {
            String category = ConsoleInput.getString("请输入预算分类：");
            double amount = ConsoleInput.getAmount("请输入预算金额：");
            String cycle = ConsoleInput.getString("请输入周期（月/季度/年）：");
            String startDateStr = ConsoleInput.getString("请输入开始日期（格式：yyyy-MM-dd）：");
            String endDateStr = ConsoleInput.getString("请输入结束日期（格式：yyyy-MM-dd）：");

            Date startDate = new SimpleDateFormat("yyyy-MM-dd").parse(startDateStr);
            Date endDate = new SimpleDateFormat("yyyy-MM-dd").parse(endDateStr);

            // 校验日期逻辑
            if (startDate.after(endDate)) {
                System.out.println("开始日期不能晚于结束日期");
                return;
            }

            Budget budget = new Budget();
            budget.setUserId(loginUser.getId());
            budget.setCategory(category);
            budget.setAmount(new BigDecimal(amount));
            budget.setCycle(cycle);
            budget.setStartDate(startDate);
            budget.setEndDate(endDate);

            budgetService.addBudget(budget);
            System.out.println("通用预算添加成功");
        } catch (ParseException e) {
            System.out.println("日期格式错误，请使用yyyy-MM-dd");
        } catch (FinanceException e) {
            System.out.println("操作失败：" + e.getMessage());
        }
    }

    // 修改预算
    private static void updateBudget() {
        int budgetId = ConsoleInput.getInt("请输入要修改的预算ID：", 1, Integer.MAX_VALUE);
        double newAmount = ConsoleInput.getAmount("请输入新预算金额：");

        try {
            budgetService.updateBudgetById(budgetId, new BigDecimal(newAmount));
            System.out.println("预算修改成功");
        } catch (FinanceException e) {
            System.out.println(e.getMessage());
        }
    }

    // 删除预算
    private static void deleteBudget() {
        int budgetId = ConsoleInput.getInt("请输入要删除的预算ID：", 1, Integer.MAX_VALUE);

        try {
            budgetService.deleteBudgetById(budgetId);
            System.out.println("预算删除成功");
        } catch (FinanceException e) {
            System.out.println(e.getMessage());
        }
    }

    // 财务统计
    private static void handleFinancialStat() {
        String yearMonth = ConsoleInput.getString("请输入年月（格式：yyyy-MM）：");
        try {
            StatResult stat = statService.statMonth(loginUser.getId(), yearMonth);
            System.out.println("\n===== " + yearMonth + " 财务统计 =====");
            System.out.println("总收入：" + stat.getTotalIncome() + "元");
            System.out.println("总支出：" + stat.getTotalExpense() + "元");
            System.out.println("月结余：" + stat.getBalance() + "元");
        } catch (FinanceException e) {
            System.out.println(e.getMessage());
        }
    }

    // 消费分析
    private static void handleConsumptionAnalysis() {
        String yearMonth = ConsoleInput.getString("请输入年月（格式：yyyy-MM）：");
        try {
            AnalysisResult result = analysisService.analyzeMonth(loginUser.getId(), yearMonth);
            System.out.println("\n===== " + yearMonth + " 消费分析 =====");

            // 支出分类占比（确保AnalysisResult返回Map<String, Double>）
            System.out.println("支出分类占比：");
            Map<String, Double> categoryRatio = result.getCategoryRatio();
            if (categoryRatio.isEmpty()) {
                System.out.println("无支出记录");
            } else {
                categoryRatio.forEach((category, ratio) ->
                        System.out.printf("%s：%.2f%%\n", category, ratio * 100)
                );
            }

            // 预算执行率
            System.out.println("预算执行率：" + result.getBudgetExecutionRate() + "%");
        } catch (Exception e) {
            System.out.println("分析失败：" + e.getMessage());
        }
    }

    // 生成报表
    private static void handleGenerateReport() {
        String yearMonth = ConsoleInput.getString("请输入年月（格式：yyyy-MM）：");
        String savePath = ConsoleInput.getString("请输入报表保存路径：");

        try {
            reportService.generateMonthReport(loginUser.getId(), yearMonth, savePath);
            System.out.println("报表已生成至：" + savePath);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    // 管理员用户管理功能
    private static void handleUserManagement() {
        while (true) {
            System.out.println("\n===== 用户管理 =====");
            System.out.println("1. 查看所有用户");
            System.out.println("2. 禁用/启用用户");
            System.out.println("3. 删除用户");
            System.out.println("4. 返回上一级");
            String choice = ConsoleInput.getString("请选择：");

            switch (choice) {
                case "1": showAllUsers(); break;
                case "2": toggleUserStatus(); break;
                case "3": deleteUser(); break;
                case "4": return;
                default: System.out.println("无效选择");
            }
        }
    }

    // 查看所有用户
    private static void showAllUsers() {
        try {
            List<User> users = userService.getAllUsers();
            System.out.println("\n===== 用户列表 =====");
            System.out.printf("%-5s %-10s %-10s %-6s %-6s %-20s%n",
                    "ID", "用户名", "真实姓名", "角色", "状态", "创建时间");
            for (User user : users) {
                String status = user.getStatus() == 1 ? "启用" : "禁用";
                System.out.printf("%-5d %-10s %-10s %-6s %-6s %-20s%n",
                        user.getId(),
                        user.getUsername(),
                        user.getRealName(),
                        user.getRole(),
                        status,
                        user.getCreateTime()
                );
            }
        } catch (SQLException e) {
            System.out.println("查询失败：" + e.getMessage());
        }
    }

    // 禁用/启用用户
    private static void toggleUserStatus() {
        int userId = ConsoleInput.getInt("请输入用户ID：");
        int status = ConsoleInput.getInt("请输入状态（1-启用，0-禁用）：");
        if (status != 0 && status != 1) {
            System.out.println("状态只能是0或1");
            return;
        }
        try {
            boolean success = userService.updateUserStatus(userId, status);
            System.out.println(success ? "操作成功" : "操作失败（用户不存在或状态未变更）");
        } catch (Exception e) {
            System.out.println("修改失败：" + e.getMessage());
        }
    }

    // 删除用户
    private static void deleteUser() {
        int userId = ConsoleInput.getInt("请输入要删除的用户ID：");
        if (userId == loginUser.getId()) {
            System.out.println("不能删除当前登录用户");
            return;
        }
        String confirm = ConsoleInput.getString("确认删除？此操作将删除用户所有财务数据（y/n）：");
        if ("y".equalsIgnoreCase(confirm)) {
            try {
                boolean success = userService.deleteUser(userId);
                System.out.println(success ? "删除成功" : "删除失败（用户不存在）");
            } catch (Exception e) {
                System.out.println("删除失败：" + e.getMessage());
            }
        }
    }

    // 系统设置
    private static void handleSystemSetting() {
        String menu = "\n===== 系统设置 =====\n" +
                "1. 数据备份\n" +
                "2. 数据恢复\n" +
                "3. 返回上一级\n" +
                "请选择：";
        String choice = ConsoleInput.getString(menu);
        switch (choice) {
            case "1":
                backupData();
                break;
            case "2":
                restoreData();
                break;
            case "3":
                return;
            default:
                System.out.println("无效选择");
        }
    }

    // 数据备份
    private static void backupData() {
        String path = ConsoleInput.getString("请输入备份路径（如D:/backup/）：");
        try {
            // 实际应用中需实现真实备份逻辑
            String fileName = "finance_backup_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".sql";
            System.out.println("数据备份成功，保存至：" + path + fileName);
        } catch (Exception e) {
            System.out.println("备份失败：" + e.getMessage());
        }
    }

    // 数据恢复
    private static void restoreData() {
        String path = ConsoleInput.getString("请输入备份文件路径：");
        String confirm = ConsoleInput.getString("确认恢复？此操作将覆盖现有数据（y/n）：");
        if ("y".equalsIgnoreCase(confirm)) {
            try {
                // 实际应用中需实现真实恢复逻辑
                System.out.println("数据恢复成功");
            } catch (Exception e) {
                System.out.println("恢复失败：" + e.getMessage());
            }
        }
    }
}